package com.guinea.core.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;

import modules.recruit.entity.ApplyBase;
import modules.recruit.entity.ApplyConfirm;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.guinea.core.Constants;
import com.guinea.core.acegi.UserDetailsImpl;
import com.guinea.core.tag.City;
import com.guinea.core.tag.DictEntry;
import com.guinea.core.tag.District;
import com.guinea.core.tag.Province;

public class CommonUtils {

	protected static final Log logger = LogFactory.getLog(CommonUtils.class);

	public static String getYear(int diff){
		Calendar c = Calendar.getInstance();
		c.add(Calendar.YEAR, diff);
		return String.valueOf(c.get(Calendar.YEAR));
	}
	
	
	/**申请是否可被修改
	 * @param applyBase
	 * @return
	 */
	public static boolean couldApplyBeModified(ApplyBase applyBase) {
		if(applyBase == null) return false;
		boolean result = false;
		if ("1".equals(applyBase.getIsSubmitted())
				&& !isRoleOfCurrentUser("role_console_user")) {
			// 是否确认完成并有1天时间
			boolean isInOneDay = false;
			ApplyConfirm applyConfirm = applyBase.getConfirm();
			Date d = null;
			if (applyConfirm != null) {
				d = applyConfirm.getUpdatedDate() == null ? applyConfirm
						.getCreatedDate() : applyConfirm.getUpdatedDate();
				if (d != null)
					isInOneDay = isInOneDay(d);
			}
			if (isInOneDay) {
				result = true;
			}
		}else{
			result = true;
		}
		return result;
	}

	public static boolean isInOneDay(String date) {
		Date d = null;
		try {
			d = Constants.DEFAULT_DATE_FORMAT.parse(date);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

		return isInOneDay(d);
	}

	public static boolean isInOneDay(Date d) {
		if (d != null) {
			Calendar c = Calendar.getInstance();
			c.setTime(d);
			c.add(c.DATE, 2);
			Calendar now = Calendar.getInstance();
			return now.before(c);
		}

		return false;
	}

	public static String formatDate(Date src) {
		if (src == null)
			return null;
		String result = null;
		try {
			result = Constants.DEFAULT_DATE_FORMAT.format(src);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	public static Long getCurrentUserId() {
		Long userId = new Long(0);
		SecurityContext s = SecurityContextHolder.getContext();
		if (s != null && s.getAuthentication() != null
				&& s.getAuthentication().getPrincipal() != null) {
			Object obj = s.getAuthentication().getPrincipal();
			if (obj instanceof UserDetailsImpl) {
				userId = ((UserDetailsImpl) obj).getId();
			}
		}

		return userId;
	}

	public static UserDetailsImpl getCurrentUser() {
		SecurityContext s = SecurityContextHolder.getContext();
		if (s != null && s.getAuthentication() != null
				&& s.getAuthentication().getPrincipal() != null) {
			Object obj = s.getAuthentication().getPrincipal();
			if (obj instanceof UserDetailsImpl) {
				return (UserDetailsImpl) obj;
			}
		}

		return null;
	}

	public static Long getCurrentUserId(HttpServletRequest request) {
		UserDetailsImpl userDetailsImpl = getCurrentUser(request);
		if (userDetailsImpl != null)
			return userDetailsImpl.getId();
		return null;
	}

	public static UserDetailsImpl getCurrentUser(HttpServletRequest request) {
		HttpSession session = request.getSession();
		SecurityContextImpl s = (SecurityContextImpl) session
				.getAttribute("ACEGI_SECURITY_CONTEXT");
		if (s == null)
			return null;
		Object obj = s.getAuthentication().getPrincipal();
		if (obj instanceof UserDetailsImpl) {
			return (UserDetailsImpl) obj;
		}

		return null;
	}

	public static UserDetailsImpl getCurrentUser(PageContext pageContext) {
		HttpSession session = pageContext.getSession();
		SecurityContextImpl s = (SecurityContextImpl) session
				.getAttribute("ACEGI_SECURITY_CONTEXT");
		if (s == null)
			return null;
		Object obj = s.getAuthentication().getPrincipal();
		if (obj instanceof UserDetailsImpl) {
			return (UserDetailsImpl) obj;
		}

		return null;
	}

	public static boolean isRoleOfCurrentUser(String roleNames) {
		UserDetailsImpl u = getCurrentUser();
		String[] roleNameArray = roleNames.split(",");
		if (u == null || roleNameArray.length < 1)
			return false;
		GrantedAuthority[] as = u.getAuthorities();
		boolean result = false;
		for (int i = 0; i < as.length; i++) {
			GrantedAuthority a = as[i];
			for (int j = 0; j < roleNameArray.length; j++) {
				String r = roleNameArray[j].trim();
				if (r.equals(a.getAuthority())) {
					return true;
				}
			}
		}
		return result;
	}

	public static Properties loadAppProperties() {
		InputStream is = CommonUtils.class
				.getResourceAsStream("../../../../application.properties");
		Properties prop = new Properties();
		try {
			prop.load(is);
		} catch (IOException e) {
			logger.error("CommonUtils -> loadAppProperties :", e);
		}
		return prop;
	}

	/**
	 * 输入输出通用方法
	 * 
	 * @auther huaxiaz
	 * @since 2009-7-27
	 * @param in
	 * @param out
	 * @return
	 */
	public static boolean io(InputStream in, OutputStream out) {
		boolean b = true;
		byte[] buffer = new byte[1024 * 4];
		try {
			int readLength;
			while ((readLength = in.read(buffer)) > -1) {
				out.write(buffer, 0, readLength);
			}
			out.flush();
			out.close();
			in.close();
		} catch (IOException e) {
			b = false;
			logger.error("io IOException errorMessage :" + e.getMessage());
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException e1) {
				logger.error("io finally IOException  errorMessage :"
						+ e1.getMessage());
			}
		}
		return b;
	}

	public static String provinceCodeToName(String code, List provinces) {
		return provinceCodeToName(code, null, provinces);
	}

	public static String dictEntryCodeToName(String code, String attr,
			List entries) {
		String result = "";
		if (code != null) {
			DictEntry dictEntry = null;
			for (Iterator iter = entries.iterator(); iter.hasNext();) {
				DictEntry p = (DictEntry) iter.next();
				if (code.equals(p.getCode())) {
					dictEntry = p;
					break;
				}
			}

			if (dictEntry != null) {
				if (StringUtils.isEmpty(attr)) {
					result = dictEntry.getName();
				}
			}
		}
		return result;
	}

	public static String provinceCodeToName(String code, String attr,
			List provinces) {
		String result = "";
		if (code != null) {
			Province province = null;
			for (Iterator iter = provinces.iterator(); iter.hasNext();) {
				Province p = (Province) iter.next();
				if (code.equals(p.getCode())) {
					province = p;
					break;
				}
			}

			if (province != null) {
				if (StringUtils.isEmpty(attr)) {
					result = province.getName();
				} else {
					Object x = ReflectionUtils.getFieldValue(province, attr);
					if (x != null)
						result = x.toString();
				}
			}
		}
		return result;
	}

	public static String provinceAbbrToCode(String abbr,
			List provinces) {
		String result = "";
		if (abbr != null) {
			abbr = abbr.trim();
			Province province = null;
			for (Iterator iter = provinces.iterator(); iter.hasNext();) {
				Province p = (Province) iter.next();
				if (abbr.equals(p.getAbbr())) {
					province = p;
					break;
				}
			}

			if (province != null) {
				result = province.getCode();
			}
		}
		return result;
	}

	public static String cityCodeToName(String code, List cities) {
		String result = "";
		if (code != null) {
			City city = null;
			for (Iterator iter = cities.iterator(); iter.hasNext();) {
				City c = (City) iter.next();
				if (code.equals(c.getCode())) {
					city = c;
					break;
				}
			}

			if (city != null) {
				result = city.getName();
			}
		}
		return result;
	}

	public static String cityNameToCode(String name, List cities) {
		String result = "";
		if (name != null) {
			name = name.trim();
			City city = null;
			for (Iterator iter = cities.iterator(); iter.hasNext();) {
				City c = (City) iter.next();
				if (name.equals(c.getName())) {
					city = c;
					break;
				}
			}

			if (city != null) {
				result = city.getCode();
			}
		}
		return result;
	}

	public static String districtCodeToName(String code, List districts) {
		String result = "";
		if (code != null) {
			District district = null;
			for (Iterator iter = districts.iterator(); iter.hasNext();) {
				District d = (District) iter.next();
				if (code.equals(d.getCode())) {
					district = d;
					break;
				}
			}

			if (district != null) {
				result = district.getName();
			}
		}
		return result;
	}

	public static String districtNameToCode(String name, List districts) {
		String result = "";
		if (name != null) {
			District district = null;
			for (Iterator iter = districts.iterator(); iter.hasNext();) {
				District d = (District) iter.next();
				if (name.equals(d.getName())) {
					district = d;
					break;
				}
			}

			if (district != null) {
				result = district.getCode();
			}
		}
		return result;
	}
}
